package com.itheima.service.impl;

import cn.hutool.core.lang.Validator;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.common.*;
import com.itheima.entity.Employee;
import com.itheima.exception.BusinessException;
import com.itheima.mapper.EmployeeMapper;
import com.itheima.service.EmployeeService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

/**
 * @author suiweihua
 * @version 1.0
 * @description: TODO 员工模块-业务层实现
 * @date 2022/6/5 15:20
 */
@Service
public class EmployeeServiceImpl implements EmployeeService {
    @Autowired
    private EmployeeMapper employeeMapper;

    /**
     * 功能描述 :分页查询员工列表
     *
     * @param page
     * @param pageSize
     * @param name
     * @return : com.baomidou.mybatisplus.extension.plugins.pagination.Page<com.itheima.domain.Employee>
     */
    @Override
    public Page<Employee> page(Integer page, Integer pageSize, String name) {
        //校验参数
        if (page < 1) {
            page = 1;
        }
        if (pageSize < 1) {
            pageSize = 10;
        }
        //创建分页条件
        Page<Employee> page1 = new Page<>(page, pageSize);
        //构建查询条件
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(name)) {
            //当name不为空时进行模糊查询
            wrapper.like(Employee::getName, name);
        }
        wrapper.orderByAsc(Employee::getCreateTime);
        //进行分页查询
        Page<Employee> pageResult = employeeMapper.selectPage(page1, wrapper);
        //返回分页查询结果
        return pageResult;
    }

    /**
     * 功能描述 :新增员工业务实现
     *
     * @param employee
     * @return : int
     */
    @Transactional(rollbackFor = Throwable.class)//开启事务要么同时成功,要么就是失败
    @Override
    public Result saveEmployee(Employee employee) {
        int row = 0;
        if (employee == null) {
            return new Result(null, null, row);
        }
        //校验参数
        String username = employee.getUsername();
        //账号为空时返回 抛出异常
        if (StringUtils.isBlank(username)) {
            return new Result(Code.ERROR, MessageConstant.EMP_ACCOUNT_NULL_ERROR);
        }
        //账号的长度小于3或者大于20的时候 抛出异常 账号输入错误
        if (username.toCharArray().length < 3 || username.toCharArray().length > 20) {
            return new Result(Code.ERROR, MessageConstant.EMP_ACCOUNT_ERROR);
        }
        //校验账号只能为中文,字母,英文,下划线
        if (!Validator.isGeneral(username)) {
            return new Result(Code.ERROR, MessageConstant.EMP_ACCOUNT_FORMAT_ERROR);
        }
        //员工姓名的长度为空时抛出异常 长度小于1或者大于12 的时候抛出异常 姓名输入错误
        String name = employee.getName();
        if (StringUtils.isBlank(name)) {
            return new Result(Code.ERROR, MessageConstant.EMP_EMPLOYEE_NULL_ERROR);
        }
        if (name.toCharArray().length < 1 || name.toCharArray().length > 12) {
            return new Result(Code.ERROR, MessageConstant.EMP_EMPLOYEE_NAME_ERROR);
        }
        //姓名只能输入中文
        if (!Validator.isChinese(name)) {
            return new Result(Code.ERROR, MessageConstant.EMP_EMPLOYEE_CHINESE_ERROR);
        }
        //手机号校验
        String phone = employee.getPhone();
        if (StringUtils.isBlank(phone)) {
            return new Result(Code.ERROR, MessageConstant.EMP_PHONE_NULL_ERROR);
        }
        String regexMobile = "^1[3|4|5|6|7|8|9]\\d{9}$|^09\\d{8}$";
        if (!phone.matches(regexMobile)) {
            return new Result(Code.ERROR, MessageConstant.EMP_PHONE_ERROR);
        }
        //身份证号校验
        String idNumber = employee.getIdNumber();
        if (StringUtils.isBlank(idNumber)) {
            return new Result(Code.ERROR, MessageConstant.EMP_ID_NUMBER_NULL_ERROR);
        }
        String regexIdNumber = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
        if (idNumber.length() != 18 || !idNumber.matches(regexIdNumber)) {
            return new Result(Code.ERROR, MessageConstant.EMP_ID_NUMBER_ERROR);
        }
        //构建查询条件 根据账号查询有无这个员工 有则返回,无则补全数据新建
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getUsername, username);
        Employee one = employeeMapper.selectOne(wrapper);
        //当有这个员工的时候 抛出异常
        if (one != null) {
            return new Result(Code.ERROR, MessageConstant.EMP_EXISTS_ERROR);
        }
        //当没有员工时 补全默认密码并加密 新建
        employee.setPassword(DigestUtils.md5DigestAsHex(EmployeeConstant.EMP_INIT_PASSWORD.getBytes()));
        //添加员工
        row = employeeMapper.insert(employee);
        return new Result(null, null, row);
    }

    /***
     * 功能描述:
     * @param employee
     * @return : com.itheima.domain.Employee
     */
    @Override
    public Employee login(Employee employee) {
        //1.1校验用户名、密码
        if (employee == null || StringUtils.isBlank(employee.getUsername()) || StringUtils.isBlank(employee.getPassword())) {
            return null;
        }
        //1.2.校验密码的长度 小于6
        if (employee.getPassword().length() < 6) {
            return null;
        }
        //2.根据用户名查询数据
        LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Employee::getUsername, employee.getUsername());
        Employee one = employeeMapper.selectOne(wrapper);
        //2.1 查询失败，用户名不存在，直接返回 NULL
        if (one == null) {
            return null;
        }
        //2.2 查询成功，用户名存在
        //3.检查用户状态（用户状态：1-启用、0-禁用）
        if (one.getStatus() == EmployeeConstant.EMPLOYEE_STATUS_DISABLE) {
            return null;
        }
        //4.比对“前端传递的密码（明文）”和“数据库密码（密文）”，需要先加密后比对
        String paramPwd = employee.getPassword();
        String encodePwd = DigestUtils.md5DigestAsHex(paramPwd.getBytes());
        //4.1 比对失败，密码错误，返回NULL
        if (!encodePwd.equals(one.getPassword())) {
            return null;
        }
        //4.2 比对成功，登录成功，返回Employee
        return one;
    }

    /**
     * 功能描述 :编辑员工
     *
     * @param id
     * @return : com.itheima.entity.Employee
     */
    @Override
    public Employee findById(Long id) {
        //校验参数
        if (id == null) {
            return null;
        }
        //根据id查询员工
        Employee employee = employeeMapper.selectById(id);
        return employee;
    }

    /**
     * 功能描述 :修改员工业务实现
     *
     * @param employee
     * @return : int
     */
    @Transactional(rollbackFor = Throwable.class)//开启事务要么同时成功,要么就是失败
    @Override
    public Result update(Employee employee) {
        int row = 0;
        if (employee == null) {
            return new Result(null, null, row);
        }
        //校验参数
        String username = employee.getUsername();
        //账号为空时返回 抛出异常
        if (StringUtils.isBlank(username)) {
            return new Result(Code.ERROR, MessageConstant.EMP_ACCOUNT_NULL_ERROR);
        }
        //账号的长度小于3或者大于20的时候 抛出异常 账号输入错误
        if (username.toCharArray().length < 3 || username.toCharArray().length > 20) {
            return new Result(Code.ERROR, MessageConstant.EMP_ACCOUNT_ERROR);
        }
        //校验账号只能为中文,字母,英文,下划线
        if (!Validator.isGeneral(username)) {
            return new Result(Code.ERROR, MessageConstant.EMP_ACCOUNT_FORMAT_ERROR);
        }
        //员工姓名的长度为空时抛出异常 长度小于1或者大于12 的时候抛出异常 姓名输入错误
        String name = employee.getName();
        if (StringUtils.isBlank(name)) {
            return new Result(Code.ERROR, MessageConstant.EMP_EMPLOYEE_NULL_ERROR);
        }
        if (name.toCharArray().length < 1 || name.toCharArray().length > 12) {
            return new Result(Code.ERROR, MessageConstant.EMP_EMPLOYEE_NAME_ERROR);
        }
        //姓名只能输入中文
        if (!Validator.isChinese(name)) {
            return new Result(Code.ERROR, MessageConstant.EMP_EMPLOYEE_CHINESE_ERROR);
        }
        //手机号校验
        String phone = employee.getPhone();
        if (StringUtils.isBlank(phone)) {
            return new Result(Code.ERROR, MessageConstant.EMP_PHONE_NULL_ERROR);
        }
        String regexMobile = "^1[3|4|5|6|7|8|9]\\d{9}$|^09\\d{8}$";
        if (!phone.matches(regexMobile)) {
            return new Result(Code.ERROR, MessageConstant.EMP_PHONE_ERROR);
        }
        //身份证号校验
        String idNumber = employee.getIdNumber();
        if (StringUtils.isBlank(idNumber)) {
            return new Result(Code.ERROR, MessageConstant.EMP_ID_NUMBER_NULL_ERROR);
        }
        String regexIdNumber = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
        if (idNumber.length() != 18 || !idNumber.matches(regexIdNumber)) {
            return new Result(Code.ERROR, MessageConstant.EMP_ID_NUMBER_ERROR);
        }
        //根据id修改
        row = employeeMapper.updateById(employee);
        return new Result(null, null, row);
    }

    /**
     * 功能描述 :员工状态禁用,启用业务
     *
     * @param employee
     * @return : int
     */
    @Transactional(rollbackFor = Throwable.class)//开启事务要么同时成功,要么就是失败
    @Override
    public int updateStatus(Employee employee) {
        int row = 0;
        //校验参数
        if (employee == null) {
            return row;
        }
        //比对是否为admin管理员用户登录
        Long currentId = BaseContext.getCurrentId();
        if (currentId == null) {
            return row;
        }
        Employee employeeAdmin = employeeMapper.selectById(currentId);
        if (!EmployeeConstant.ADMIN.equals(employeeAdmin.getUsername())) {
            throw new BusinessException(Code.ERROR, MessageConstant.ADMINISTRATOR_NOT_LOGIN);
        }
        //获取当前的状态
        Integer status = employee.getStatus();
        //构造修改条件
        Long id = employee.getId();
        LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Employee::getStatus, status);
        wrapper.eq(Employee::getId, id);
        row = employeeMapper.update(null, wrapper);
        return row;
    }

    /**
     * 功能描述 :批量删除员工
     *
     * @param ids
     * @return : int
     */
    @Transactional(rollbackFor = Throwable.class)//开启事务要么同时成功,要么就是失败
    @Override
    public int delete(Long[] ids) {
        int row = 0;
        //校验参数
        if (ids == null) {
            return row;
        }
        //比对是否为admin管理员用户登录
        Long currentId = BaseContext.getCurrentId();
        if (currentId == null) {
            return row;
        }
        Employee employee = employeeMapper.selectById(currentId);
        if (!EmployeeConstant.ADMIN.equals(employee.getUsername())) {
            throw new BusinessException(Code.ERROR, MessageConstant.ADMINISTRATOR_NOT_LOGIN);
        }
        //构造修改条件,删除员工
        LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
        wrapper.in(Employee::getId, ids);
        row = employeeMapper.delete(wrapper);
        return row;
    }
}
